package high.concurrent.controller;

import high.concurrent.component.OutTradeNoComponent;
import high.concurrent.enums.OrderStateEnum;
import high.concurrent.enums.PayClientTypeEnum;
import high.concurrent.enums.PayTypeEnum;
import high.concurrent.mapper.ProductOrderMapper;
import high.concurrent.model.ProductOrderModel;
import high.concurrent.request.CreateOrderRequest;
import high.concurrent.server.ProductOrderService;
import high.concurrent.util.WeixinUtil;
import high.concurrent.util.XMLUtil;
import high.concurrent.utils.JsonData;
import high.concurrent.vo.PayInfoVO;
import high.concurrent.vo.ProductOrderVO;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.redisson.codec.JsonJacksonCodec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

@RestController
@Slf4j
@RequestMapping("/api/v1/order")
public class ProductOrderController {

    @Autowired(required = false)
    private ProductOrderMapper productOrderMapper;

    @Autowired
    private ProductOrderService productOrderService;

    @Autowired
    private OutTradeNoComponent outTradeNoComponent;

    /**
     * 根据订单号查询订单信息
     * @param outTradeNo  订单号
     * @return
     */
    @GetMapping("selectOrderByOutTradeNo")
    public JsonData selectOrderByOutTradeNo(@RequestParam("outTradeNo") String outTradeNo){

        ProductOrderVO productOrderVO = productOrderService.selectOrderByOutTradeNo(outTradeNo);
        return JsonData.buildSuccess(productOrderVO);
    }

    /**
     * 根据商家id查询订购单集合
     * @param businessId  商户id
     * @param page  当前页数
     * @param pageSize  每页数据量
     * @return
     */
    @GetMapping("selectOrderByBusinessId")
    public JsonData selectOrderByBusinessId(@RequestParam("businessId") Long businessId,
                                            @RequestParam("page") Integer page, @RequestParam("pageSize") Integer pageSize){
        List<ProductOrderVO> productOrderVOList = productOrderService.selectOrderByBusinessId(businessId, page, pageSize);
        return JsonData.buildSuccess(productOrderVOList);
    }

    /**
     * 根据用户id查询订购单集合
     * @param page  当前页数
     * @param pageSize  每页数据量
     * @return
     */
    @GetMapping("selectOrderByUserId")
    public JsonData selectOrderByUserId(@RequestParam("page") Integer page, @RequestParam("pageSize") Integer pageSize){
        List<ProductOrderVO> productOrderVOList = productOrderService.selectOrderByUserId(page, pageSize);
        return JsonData.buildSuccess(productOrderVOList);
    }

    /**
     * 获取下单防重令牌token
     * @param accountId 用户id
     * @return
     */
    @ApiOperation("获取下单防重令牌token")
    @GetMapping("getOrderRepayToken")
    public JsonData getOrderRepayToken(@RequestParam Long accountId){

        JsonData jsonData = productOrderService.getOrderRepayToken(accountId);
        return jsonData;
    }

    /**
     * 提交订单
     * @param response
     * @param createOrderRequest
     */
    @ApiOperation("提交订单")
    @PostMapping("confirmOrder")
    public JsonData confirmOrder(HttpServletResponse response, HttpServletRequest request,
                             @ApiParam("订单参数") @RequestBody CreateOrderRequest createOrderRequest){
        JsonData jsonData = productOrderService.confirmOrder(createOrderRequest, request);
        return JsonData.buildSuccess(jsonData);
    }

    /**
     * 测试添加
     */
    @GetMapping("testAddOrder")
    public String testAddOrder(){

        List<String> userName = Arrays.asList("张三", "李四", "王五", "刘六", "李奇", "王八", "赵九", "史珍香", "路人甲",
                "路人乙", "路人丙", "路人丁", "测试人1", "测试人2", "测试人3", "测试人4", "测试人5", "测试人6", "测试人7",
                "测试人8", "测试人9", "测试人10", "测试人11", "测试人12", "测试人13", "测试人14", "测试人15", "测试人16",
                "测试人17", "测试人18", "测试人19", "测试人20", "测试人21", "测试人22", "测试人23", "测试人24", "测试人25",
                "测试人26", "测试人27", "测试人28", "测试人29", "测试人30", "测试人31", "测试人32", "测试人33", "测试人34",
                "测试人35", "测试人36", "测试人37", "测试人38", "测试人39", "测试人40", "测试人41", "测试人42", "测试人43");

        List<String> orderTypes = Arrays.asList("NORAL", "VIP", "NORAL", "NORAL");

        List<String> payTypes = Arrays.asList("JD", "ALIPAY", "WEIXIN");

        List<String> recveiverAddresses = Arrays.asList("辽宁省-大连市", "辽宁省-沈阳市", "上海市", "北京市", "广东省-深圳市");

        List<String> states = Arrays.asList("PAY", "NEW", "CANCEL");
        AtomicLong count = new AtomicLong(0);
        for(int j = 0; j< 3; j++){

            new Thread(()->{
                for(long i = 0; i < 100000000; i++){
                    Random random = new Random();
                    int userId = random.nextInt(55);
                    int orderType = random.nextInt(4);
                    int payType = random.nextInt(3);
                    int recveiverAddress = random.nextInt(5);
                    int state = random.nextInt(3);

//                    System.err.println("订单类型: " + orderTypes.get(orderType)+ ", 支付类型：" + payTypes.get(payType) + ", 收货地址: " + recveiverAddresses.get(recveiverAddress) + ", 订单状态：" + states.get(state));
                    ProductOrderModel productOrderModel = new ProductOrderModel();
                    productOrderModel.setBusinessId((long) random.nextInt(1000));
                    productOrderModel.setUserId((long) userId);
                    productOrderModel.setNickname(userName.get(userId));
                    productOrderModel.setCreateTime(new Date());
                    productOrderModel.setHeadImg("1");
                    productOrderModel.setOrderType(orderTypes.get(orderType));
                    productOrderModel.setOutTradeNo(outTradeNoComponent.createOutTradeNo());
                    productOrderModel.setPayAmount(new BigDecimal(20.00));
                    productOrderModel.setTotalAmount(new BigDecimal(25.00));
                    productOrderModel.setPayType(payTypes.get(payType));
                    productOrderModel.setQrCodeImg("http://www.baidu.com");
                    productOrderModel.setReceiverAddress(recveiverAddresses.get(recveiverAddress));
                    productOrderModel.setState(states.get(state));
                    productOrderModel.setUpdateTime(new Date());
                    productOrderMapper.insert(productOrderModel);
                    count.addAndGet(1);
                    System.err.println("已添加数据: " + count + "条");
                }
            }).start();

        }
        return "正在执行...";

    }


    /**
     * 微信支付回调(通知微信支付成功失败,微信返回给客户端)
     * @param request
     * @param response
     */
    @RequestMapping(value = {"/wx_notify"}, method = {RequestMethod.POST})
    public String saveWxOrderNotify(HttpServletRequest request, HttpServletResponse response) {

        log.info("进入微信回调");
        // 默认返回失败
        String result = WeixinUtil.setXml("FAIL", "OK");
        try {
            // 把返回的参数转成MAP
            Map<String, String> paramsMap = this.checkNotify(request, response);
            // 微信支付状态校验
            if (paramsMap != null && "SUCCESS".equals(paramsMap.get("return_code"))) { // 支付成功
                // 生成秘钥
                String endsign = WeixinUtil.checkSign(paramsMap);
                if (endsign.equals(paramsMap.get("sign"))) {
                    // 取出支付订单号
                    String out_trade_no = paramsMap.get("out_trade_no");
                    log.info("微信回调的订单号：" + out_trade_no);
                    // 回调有对库的一些操作
                    String rtn = this.returnRrlPath(out_trade_no);
                    result = WeixinUtil.setXml("SUCCESS", "OK");
                }else{

                    log.info("验签失败, serverSign = {}, localSign = {}", endsign, paramsMap.get("sign"));
                }
            }
            log.info("微信支付状态错误, stgatus = {}",paramsMap.get("return_code"));
            return result;
        } catch (Exception var8) {
            log.error(var8.getMessage(), var8);
            return result;
        } finally {
            log.info("微信回调结束");
        }
    }


    /**
     * 微信回调格式化
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public Map<String, String> checkNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), Charset.forName("UTF-8")));
        String line = null;
        StringBuffer sb = new StringBuffer();

        while((line = reader.readLine()) != null) {
            sb.append(line);
        }

        Map<String, String> map = XMLUtil.doXMLParse(sb.toString());
        return map;
    }


    /**
     * 支付回调后的业务处理
     * @param outTradeNo
     * @return
     */
    private String returnRrlPath(String outTradeNo) {

        // 第一步：根据支付订单号查询支付订单详情
        ProductOrderVO productOrderVO = productOrderService.selectOrderByOutTradeNo(outTradeNo);

        // 如果订单状态为未支付，则再走回调逻辑
        if(OrderStateEnum.PAY.name().equalsIgnoreCase(productOrderVO.getState())) {
            // 回调逻辑执行
            productOrderService.returnRrlPath(productOrderVO);
        }
        return "0";

    }

}
